
	/***********************************************************************************************
	  
		Class: Node 																				

		Constructor:
			node	Node										(name*)							sid: 5.0

		Generics:	
			d			getDepth								()									sid: 5.0

			v			getValue								()									sid: 5.0
			node	setValue								(value)							sid: 5.0
			
			type	getType									()									sid: 5.0
			node	setType									(type)							sid: 5.0
			
			v			getAttribute						(id)								sid: 5.0						
			node	setAttribute						(id, value)					sid: 5.0
			node	removeAttribute					(id)								sid: 5.0
			b			hasAttributes						()									sid: 5.0
			b			hasAttribute						(id)								sid: 5.0
			
			node	setAttributes						(attributes)				sid: 5.0
			atts	getAttributes						()									sid: 5.0

		Navigation
			b			walk										(action)						sid: 5.0
			b			walkUp									(action)						sid: 5.0

		Link:
			node	attach									(parent, idx*)			sid: 5.0
			node	detach									()									sid: 5.0
			node	insertBefore						(node)							sid: 5.0					
			node	insertAfter							(node)							sid: 5.0
			
			node	appendChild							(node)							sid: 5.0
			node	appendChilds						(nodes..)						sid: 5.0
			node	removeChilds						()									sid: 5.0
			node	remove									(nodes..)						sid: 5.0
			node	replace									(node)							sid: 5.0
		
		Queries:			
			node	getRoot									()									sid: 5.0
			nodes	getLeafs								()									sid: 5.0
			nodes	getParent								()									sid: 5.0
			nodes	getChilds								()									sid: 5.0
			nodes	getSiblings							()									sid: 5.0
			nodes	getAncestors						()									sid: 5.0
			nodes getDescendants					()									sid: 5.0
						
			node	getFirstChild						()									sid: 5.0
			node	getLastChild						()									sid: 5.0
			node	getPreviousSibling			()									sid: 5.0
			node	getNextSibling					()									sid: 5.0
						
			b			hasParent								()									sid: 5.0
			b			hasChilds								()									sid: 5.0
			b			hasSiblings							()									sid: 5.0
			b			descendFrom							(ancestor)					sid: 5.0
			
			n			getChildsCount					()									sid: 5.0

			nodes	select									(qpath, filter*)		sid: 5.0		
								
		Legend:
			
			filter	f(node) -> b(filter pass) 
			action	f(node)	-> b(stop)
			nodes		array pf nodes
			qpath		query path
		
		Query path legend:
			
			syntax:
				[selector][filter]?[predicate].. 
			
			selector:		
				r 	root
				f 	leafs
				c		child
				s		sibling
				a		anchestors
				d		descendant
			
			filter: 		(id[<|<=|>|>=|=|!=|/]v)
			filter-ids: value, name, type, depth, $attribute 
			
			capture:
				*		all
				l		last
				i		integer
					
	************************************************************************************************/
	
	jsl.Class("jsl.Node", {
		
		//Private data
		//-------------------------------------------------------------------------------
		__value:	null, 
		__type:		null,
		__parent: null,
		__childs: null,
		__atts:		null,
		__cidx:		0		,
			
		//-------------------------------------------------------------------------------
		Node: function(name) {//@d[			
			if(arguments.length > 1)	throw jsl.ParamError()//@d]			

			this.__childs	= []
			this.__atts		= {}
			
			if(arguments.length) {//@d[
				jsl.validate(name, "s+", "name")//@d]
				this.__name	= name + ""
				this.__type	= name + ""
			}
		},
		//-------------------------------------------------------------------------------
		getDepth: function() {			
			var d, p
			//@d[			
			if(arguments.length)	throw jsl.ParamError()//@d]			
			
			d = 0
			p = this.__parent
			
			while(p) {
				d++
				p = p.__parent
			}
			
			return d
		},
		//-------------------------------------------------------------------------------
		getValue: function() {//@d[			
			if(arguments.length)	throw jsl.ParamError()//@d]			
			return this.__value
		},
		//-------------------------------------------------------------------------------
		setValue: function(value) {//@d[			
			if(arguments.length !== 1)	throw jsl.ParamError()//@d]			
			this.__value = value
			return this
		},
		//-------------------------------------------------------------------------------
		getType: function() {//@d[			
			if(arguments.length)	throw jsl.ParamError()//@d]			
			return this.__type
		},
		//-------------------------------------------------------------------------------
		setType: function(type) {//@d[			
			if(arguments.length !== 1)	throw jsl.ParamError()
			jsl.validate(type, "s+", type)//@d]
						
			this.__type = type + ""
			return this
		},
		//-------------------------------------------------------------------------------
		getAttribute: function(id) {//@d[			
			if(arguments.length !== 1)	throw jsl.ParamError()
			jsl.validate(id, "s+", id)//@d]
						
			return this.__atts[id]
		},
		//-------------------------------------------------------------------------------
		setAttribute: function(id, value) {//@d[			
			if(arguments.length !== 2)	throw jsl.ParamError()			
			jsl.validate(id, "s+", "id")//@d]
			
			this.__atts[id] = value 
			return this
		},
		//-------------------------------------------------------------------------------
		removeAttribute: function(id) {//@d[			
			if(arguments.length !== 1)	throw jsl.ParamError()			
			jsl.validate(id, "s+", "id")//@d]
			
			delete this.__atts[id]			
			return this
		},
		//-------------------------------------------------------------------------------
		hasAttributes: function() {
			var atts, id, hasA
			
			//@d[			
			if(arguments.length)	throw jsl.ParamError()//@d]			
			
			atts = this.__atts
			for(id in atts)
				if(atts.hasOwnProperty(id)) {					
					hasA = true
					break
				}
				
			return !!hasA
		},
		//-------------------------------------------------------------------------------
		setAttributes: function(attributes) {
			//@d[			
			if(arguments.length !== 1)	throw jsl.ParamError()
			jsl.validate(attributes, "o", "attributes")//@d]			
			
			for(var id in attributes)
				if(attributes.hasOwnProperty(id)) 			
					this.__atts[id] = attributes[id] 				
				
			return this
		},
		//-------------------------------------------------------------------------------
		getAttributes: function() {
			//@d[			
			if(arguments.length)	throw jsl.ParamError()//@d]										
			return jsl.Object.clone(this.__atts)
		},
		//-------------------------------------------------------------------------------
		hasAttribute: function(id) {//@d[			
			if(!arguments.length || arguments.length > 2)	throw jsl.ParamError()			
			jsl.validate(id, "s+", "id")//@d]
			
			return this.__atts.hasOwnProperty(id)
		},
		//-------------------------------------------------------------------------------
		walk: function(action) {
			var cs, l, b
			//@d[
			if(arguments.length !== 1)	throw jsl.ParamError()
			jsl.validate(action, "f", "action)")//@d]
	
			try 			{ b = action(this) 															}
			catch(e) 	{	throw jsl.ScriptError("BadScript:action", e) 	}
			
			if(b == null || b) {

				cs	= this.__childs
				l		= cs.length

				for(var a = 0; a < l && (b == null || b); a++)
					b = cs[a].walk(action)
			}
				
			return b == null || !!b
		},
		//-------------------------------------------------------------------------------
		walkUp: function(action) {
			var node, b
			//@d[
			if(arguments.length !== 1)	throw jsl.ParamError()
			jsl.validate(action, "f", "action)")//@d]

			node = this
			
			try {
				do {
					b 		= action(node)
					node 	= node.__parent
				} while(node && (b == null || b))			
			}
			catch(e)  {
				throw jsl.ScriptError("BadScript:action", e)
			}			
			return b == null || !!b
		},		
		//-------------------------------------------------------------------------------
		attach: function(parent, idx) {			
			var p, cs, l
			//@d[
			if(!arguments.length || arguments.length > 2)	throw jsl.ParamError()			
			if(parent == null)														throw jsl.ParamError("NullValue:	parent")
			if(!jsl.Node.isClassOf(parent))								throw jsl.ParamError("BadType:		parent:jsl.Node")
			if(this === parent)														throw jsl.ParamError("BadValue:		parent = this")
			if(arguments.length === 2)										jsl.validate(idx ,"i+", "idx")//@d]

			p = parent//@d[						
			while((p = p.__parent)) 
				if(p === this)	throw jsl.ParamError("CircularReference:parent")//@d]

			if(this.__parent !== parent || this.__cidx !== (idx || 0)) {

				if(this.__parent)		
					this.detach()
								
				this.__parent = parent						
				
				if(idx == null) {
					
					this.__cidx	= parent.__childs.length
					parent.__childs.push(this)
				}
				else {				
					this.__cidx = idx > parent.__childs.length ? parent.__childs.length : idx
					parent.__childs.splice(idx, 0, this)

					cs 	= this.__parent.__childs
					l		= cs.length
					
					for(var a = this.__cidx + 1; a < l; a++) cs[a].__cidx++ 					
				}				
			}
			return this
		},
		//-------------------------------------------------------------------------------
		detach: function() {						
			var cs, l
			
			//@d[
			if(arguments.length)	throw jsl.ParamError()//@d]
									
			if(this.__parent)	{
				
				cs 	= this.__parent.__childs
				l		= cs.length
				
				for(var a = this.__cidx + 1; a < l; a++) cs[a].__cidx-- 
				cs.splice(this.__cidx, 1)

				this.__parent = null
			}
			return this
		},
		//-------------------------------------------------------------------------------
		insertBefore: function(node) {			
			var p, idx
			//@d[
			if(arguments.length !== 1)			throw jsl.ParamError()			
			if(node == null)								throw jsl.ParamError("NullValue:	node")
			if(!jsl.Node.isClassOf(node))		throw jsl.ParamError("BadType:		node:jsl.Node")//@d]
			
			p = node.__parent//@d[
			if(!p) throw jsl.ParamError("NullValue:node(parent)")//@d]
						
			if(this !== node) {
				
				if(this.__parent === node.__parent && this.__cidx < node.__cidx)	idx = node.__cidx - 1
				else																															idx = node.__cidx
				
				this.attach(p, idx)
			}	
			return this
		},
		//-------------------------------------------------------------------------------
		insertAfter: function(node) {			
			var p, idx
			//@d[
			if(arguments.length !== 1)			throw jsl.ParamError()			
			if(node == null)								throw jsl.ParamError("NullValue:	node")
			if(!jsl.Node.isClassOf(node))		throw jsl.ParamError("BadType:		node:jsl.Node")//@d]
			
			p = node.__parent//@d[
			if(!p) throw jsl.ParamError("NullValue:node(parent)")//@d]
			
			if(this !== node) {

				if(this.__parent === node.__parent && this.__cidx < node.__cidx)	idx = node.__cidx 
				else																															idx = node.__cidx + 1
				
				this.attach(p, idx)
			}
			return this
		},
		//-------------------------------------------------------------------------------
		appendChild: function(node) {//@d[			
			if(arguments.length !== 1)		throw jsl.ParamError()			
			if(node == null)							throw jsl.ParamError("NullValue:	node")
			if(!jsl.Node.isClassOf(node))	throw jsl.ParamError("BadType:		node:jsl.Node")//@d]
			
			if(node.__parent !== this)
				node.attach(this)
				
			return this			
		},
		//-------------------------------------------------------------------------------
		appendChilds: function() {
			var a, l, node, nodes
			//@d[						
			if(!arguments.length)	throw jsl.ParamError()//@d]			

			nodes = []						
			for(a = 0, l = arguments.length; a < l; a++) 
				nodes = nodes.concat(arguments[a])
			
			for(a = 0, l = nodes.length; a < l ; a++) {
				
				node = nodes[a]//@d[
				if(node == null)							throw jsl.ParamError("NullValue:	node")
				if(!jsl.Node.isClassOf(node))	throw jsl.ParamError("BadType:		node:jsl.Node")//@d]				

				if(node.__parent !== this)
					node.attach(this)
			}			
			return this
		},
		//-------------------------------------------------------------------------------
		removeChilds: function() {			
			var cs
			//@d[
			if(arguments.length)	throw jsl.ParamError()//@d]						
			
			cs = this.__childs
			while(cs[0])
				cs[0].detach()
				
			return this
		},
		//-------------------------------------------------------------------------------
		remove: function() {			
			var a, l, node, nodes
			//@d[
			if(!arguments.length)	throw jsl.ParamError()//@d]
			
			nodes = []						
			for(a = 0, l = arguments.length; a < l; a++) 
				nodes = nodes.concat(arguments[a])
				
			for(a = 0, l = nodes.length; a < l; a++) {
				
				node = nodes[a]
				//@d[
				if(node == null)							throw jsl.ParamError("NullValue:	node[" + a + "]")
				if(!jsl.Node.isClassOf(node))	throw jsl.ParamError("BadType:		node[" + a + "]:jsl.Node")//@d]
				
				if(node.__parent)			
					node.detach()
			}
			
			return this
		},						
		//-------------------------------------------------------------------------------
		replace: function(node) {
			var p, cs
			//@d[			
			if(arguments.length !== 1)			throw jsl.ParamError()			
			if(node == null)								throw jsl.ParamError("NullValue:	node")
			if(!jsl.Node.isClassOf(node))		throw jsl.ParamError("BadType:		node:jsl.Node")//@d]
			
			//a node can be replace with itself
			if(this !== node) {

				//also a node without a parent can be replaced (parent = null) 	
				this.detach()	
				node.detach()	
				
				p 	= this.__parent
				cs 	= this.__childs
								
				while(cs[0])
					cs[0].attach(node)
				
				if(p) 					
					node.attach(p, this.__cidx)				
			}
			return this			
		},
		//-------------------------------------------------------------------------------
		getRoot: function() {
			var r			
			//@d[			
			if(arguments.length)	throw jsl.ParamError()//@d]			
			
			this.walkUp(function(node) { if(!node.__parent) r = node })			
			return r
		},				
		//-------------------------------------------------------------------------------
		getLeafs: function() {
			var lfs = []		
			//@d[			
			if(arguments.length)	throw jsl.ParamError()//@d]			
			this.walk(function(node) { if(!node.__childs.length) lfs.push(node) })			
			return lfs
		},				
		//-------------------------------------------------------------------------------
		getParent: function() {//@d[			
			if(arguments.length)	throw jsl.ParamError()//@d]			
			return this.__parent
		},				
		//-------------------------------------------------------------------------------
		getChilds: function() {//@d[			
			if(arguments.length)	throw jsl.ParamError()//@d]						
			return this.__childs.slice()
		},				
		//-------------------------------------------------------------------------------
		getSiblings: function() {			
			var ss

			//@d[
			if(arguments.length)	throw jsl.ParamError()//@d]						
			
			if(this.__parent) {
				ss = this.__parent.__childs.slice()
				ss.splice(this.__cidx, 1)
			}
			else 
				ss = []
			
			return  ss
		},				
		//-------------------------------------------------------------------------------
		getAncestors: function() {			
			var as, p
			//@d[
			if(arguments.length)	throw jsl.ParamError()//@d]						
			
			as 	= []
			p 	= this.__parent
			
			while(p) {
				as.push(p)
				p = p.__parent
			}			
			
			return  as
		},				
		//-------------------------------------------------------------------------------
		getDescendants: function() {			
			var ds, p
			//@d[
			if(arguments.length)	throw jsl.ParamError()//@d]						
			
			ds = []
			this.walk(function(node) { ds.push(node) })
			
			ds.splice(0, 1)						
			return  ds
		},				
		//-------------------------------------------------------------------------------
		getFirstChild: function() {//@d[			
			if(arguments.length)	throw jsl.ParamError()//@d]						
			return this.__childs[0] || null
		},				
		//-------------------------------------------------------------------------------
		getLastChild: function() {//@d[			
			if(arguments.length)	throw jsl.ParamError()//@d]						
			return this.__childs.length ? this.__childs[this.__childs.length - 1] : null
		},				
		//-------------------------------------------------------------------------------
		getPreviousSibling: function() {//@d[			
			if(arguments.length)	throw jsl.ParamError()//@d]						
			return this.__parent != null && (this.__parent.__childs[this.__cidx - 1] || null) || null
		},				
		//-------------------------------------------------------------------------------
		getNextSibling: function() {//@d[			
			if(arguments.length)	throw jsl.ParamError()//@d]						
			return this.__parent != null && (this.__parent.__childs[this.__cidx + 1] || null) || null
		},				
		//-------------------------------------------------------------------------------
		hasParent: function() {//@d[			
			if(arguments.length)	throw jsl.ParamError()//@d]			
			return !!this.__parent
		},				
		//-------------------------------------------------------------------------------
		hasChilds: function() {//@d[			
			if(arguments.length)	throw jsl.ParamError()//@d]						
			return !!this.__childs.length
		},				
		//-------------------------------------------------------------------------------
		hasSiblings: function() {//@d[			
			if(arguments.length)	throw jsl.ParamError()//@d]						
			return this.__parent != null && this.__parent.__childs.length > 1
		},				
		//-------------------------------------------------------------------------------
		descendFrom: function(ancestor) {			
			var b
			//@d[			
			if(arguments.length !== 1)				throw jsl.ParamError()			
			if(ancestor == null)							throw jsl.ParamError("NullValue:	ancestor")
			if(!jsl.Node.isClassOf(ancestor))	throw jsl.ParamError("BadType:		ancestor:jsl.Node")//@d]
			
			b = true
			
			if(ancestor !== this)
				this.walkUp(function(cnode){ return b = cnode !== ancestor })					
	
			return !b
		},				
		//-------------------------------------------------------------------------------
		getChildsCount: function() {//@d[			
			if(arguments.length)	throw jsl.ParamError()//@d]						
			return this.__childs.length
		},
		//-------------------------------------------------------------------------------
		select: function(qpath, filter) {
			try {
				var qp, sel, reN, reExp, node, nodes, c, c2, i, f, n, dnodes, a, l, list
				
				//@d[
				if(!arguments.length || arguments.length > 2)	throw jsl.ParamError()
				jsl.validate(qpath, "s+", "qpath")	
				if(arguments.length === 2) jsl.validate(filter, "f", "filter")
				//@d]
				
				qp		= qpath
				sel 	= qp.charAt(0)
				reN		= /^[+-]?[1-9][0-9]*/
				reExp	= /\(([^=<>!\/\)]+)([=<>!\/]{1,2})/
				node	= this
				nodes = null
							
				switch(sel) {
					
					//1° - ascendants					
					case "a":
						nodes = []
						
						node.walkUp(function(node) { nodes.push(node) })									
						nodes.shift()
						break	
					
					//2° - childs	
					case "c":
						nodes = node.__childs.slice()
						break	
					
					//3° - descendants	
					case "d":
						nodes = []
						node.walk(function(node) { nodes.push(node) })
						nodes.shift()
						break									
					
					//4° - siblings	
					case "s":
						if(node.__parent) { nodes = node.__parent.__childs.slice(); nodes.splice(this.__cidx, 1) }		
						else							  nodes = []
						break	
					
					//5° - leafs	
					case "f":
						nodes = []
						node.walk(function(node) { if(!node.__childs.length) nodes.push(node) })
						break
						
					//6° - root	
					case "r":
						this.walkUp(function(node) { if(!node.__parent) nodes = [ node ] })				
						break
						
					//7° - error	
					default:
						throw jsl.ParamError("SyntaxError:qpath")
				}
									
				c = qp.charAt(1)					
				
				//@d[
				if(sel === "r" && (c === "(" || ("radscf").indexOf(c) === -1))	throw jsl.ParamError("SyntaxError:qpath")//@d]
				
				if(sel !== "r") {											

					i = 1
	
					//filter
					if(c === "(") {
						
						f = qp.slice(1).match(reExp)//@d[
						if(!f)	throw jsl.ParamError("SyntaxError:qpath")//@d]
						
						i += f[0].length
						c2 = qp.charAt(i)
							
						if(f[2] === "/") 			f[3] = qp.slice(i).match(/(^(\\.|[^\/\\])*\/)\)/) 
						else if(c2 === "\"") 	f[3] = qp.slice(i).match(/(^"(\\.|[^"\\])*")\)/)
						else if(c2 === "'")		f[3] = qp.slice(i).match(/(^'(\\.|[^'\\])*')\)/)
						else 									f[3] = qp.slice(i).match(/([^\)]+)\)/)	
						
						//@d[
						if(!f[3])	throw jsl.ParamError("SyntaxError:qpath")//@d]
						f[3] = f[3][1]
						
						for(a = 0; nodes[a]; a++)
							if(!nodes[a].__filter(f[1], f[2], f[3])) 
								nodes.splice(nodes[a + 1] ? a-- : a, 1)
						
						i	= i + f[3].length + 1
						c = qp.charAt(i)															
					}
					//@d[
					if(!c) 												throw jsl.ParamError("SyntaxError:qpath")
					if(c === "-" && sel !== "s")	throw jsl.ParamError("SyntaxError:qpath")//@d]
					
					c2 = qp.charAt(i + 1)
					
					if(c + c2 === "++" || c + c2 === "--") {
						//@d[
						if(sel !== "s")	throw jsl.ParamError("SyntaxError:qpath")//@d]
						i++
					}
					else if(c !== "*" && (c !== "l" || c2 === "-")) {	
						n = qp.slice(c === "l" ? ++i : i).match(reN)
						i = i + (n ? n[0].length : 0) 
						n = +(n && n[0] || NaN)
						//@d[
						if(isNaN(n))	throw jsl.ParamError("NaNValue:qpath(" + qp.slice(i).match(reN) + ")")//@d]
					}
								
					//capture						
					if(c !== "*")
						if(c === "l")																			nodes = [ nodes[nodes.length - 1 + (n || 0)] ]
						else if(sel === "s" && c + c2 === "++")						nodes = nodes.slice(this.__cidx)
						else if(sel === "s" && c + c2 === "--")						nodes = nodes.slice(0, this.__cidx)
						else if(sel === "s" && (c === "+" || c === "-"))	nodes = [ nodes[this.__cidx + (n > 0 ? n - 1 : n)]	]
						else 							 																nodes = [ nodes[n - 1] ]
				}
				else
					i = 0
									
				//depth search		
				if(i < qp.length - 1) {
						
					dnodes 	= []
					qp			= qp.slice(i + 1)
					
					for(a = 0, l = nodes.length; a < l; a++) 
						if(nodes[a])
							dnodes = dnodes.concat(nodes[a].select(qp) || [])					
					
					nodes = dnodes					
				}
				
				//applicates a filter over the result
				if(filter) 
					try 			{	for(a = 0; nodes[a]; a++) if(!filter(nodes[a])) nodes.splice(nodes[a + 1] ? a-- : a, 1) }
					catch(e) 	{ throw jsl.ScriptError("BadScript:filter") 																							}
				
				qp 		= qpath.replace(/^(\\.|[^\/\\])*\//g, "")	
				list	= qp.indexOf("*") !== -1 || c + c2 === "++" || c + c2 === "--"
									
				if(list)	nodes = nodes.length ? jsl.__mlang.array_unique.call(nodes) : null
				else 			nodes = nodes[0] || null
							
				return nodes	
			}
			catch(e) {
				//no multiple stacktrace line like jsl.Node.select("...")
				if(e instanceof jsl.SyntaxError || e instanceof jsl.ScriptError) 	throw e.clearStackTrace()
				else																															throw e
			}
		},
		//private
		//-------------------------------------------------------------------------------
		__filter: function(att, op, v) {
			var b, data,  n
			
			switch(att) {
				
				case "name": 		data = this.__name; 		break
				case "value": 	data = this.__value; 		break
				case "type": 		data = this.__type; 		break
				case "depth": 	data = this.getDepth(); break
				
				default:
					//@d[
					if(att.charAt(0) !== "$")							throw jsl.ParamError("SyntaxError:qpath(" + att + ")")
					if(!this.hasAttribute(att.slice(1)))	throw jsl.ParamError("NotFound:qpath(" + att + ")")//@d]
					data = this.__atts[att.slice(1)]
			}
			
			v = v.replace(/[\n\s]+/g, "")
			
			//if the string value is not a primitive value, a re or a valid number it is treated as string 
			switch(v) {
				
				case "null": 			v = null; 			break
				case "undefined": v = undefined; 	break
				case "true": 			v = true; 			break
				case "false": 		v = false; 			break
				case "NaN": 			v = NaN; 				break
				case "Infinity": 	v = Infinity;		break				
				case "+Infinity": v = Infinity;		break				
				case "-Infinity": v = -Infinity;	break
				
				default:

					if(v.match(/^"(\\.|[^"\\])*"$/))			v = v.slice(1, -1)
					else if(v.match(/^'(\\.|[^'\\])*'$/))	v = v.slice(1, -1)
					else if(op !== "/" || !v.match(/^(\\.|[^\/\\])*\/$/)) {
						n = +v
						if(!isNaN(n))	v = n
					}
			}
							
			switch(op) {
				
				case "=":
					b = data === v
					break
				case "!=":
					b = data !== v
					break
				case "<":
					b = data < v
					break
				case "<=":
					b = data <= v
					break
				case ">":
					b = data > v
					break
				case ">=":
					b = data >= v
					break
				case "/":
					//@d[
					if(!jsl.isString(v))	throw jsl.ParamError("BadType:filter(value):string")//@d]
					b = RegExp(v.slice(0, -1)).test(data) 					
					break
				default:
					throw jsl.ParamError("SyntaxError:qpath(filter=[" + att + op + v + "])")
			}				
			return b
		}		
	})
	